<template>
  <div class="role-page">
    <div class="main">
      <div class="header">
        <p class="title">角色管理</p>
        <div class="search-container">
          <div class="search-input">
            <ul class="tabs">
              <li :class="classType === '1' ? 'active' : ''" @click="tabChange('1')">通用</li>
              <li :class="classType === '2' ? 'active' : ''" @click="tabChange('2')">私有</li>
              <li :class="classType === '' ? 'active' : ''" @click="tabChange('')">全部</li>
            </ul>
          </div>
          <div class="btns">
            <el-button v-if="hasTabAdd" type="primary" @click="handleAdd">
              新建角色
            </el-button>
          </div>
        </div>
      </div>
      <div class="content">
        <div class="table-container">
          <el-table
            row-key="id"
            v-loading="tableLoading"
            :data="tableData"
            highlight-current-row
            :current-row-key="currentKey"
            @row-click="handleRowClick">
            <el-table-column label="序号" type="index" width="80"></el-table-column>
            <el-table-column prop="roleName" label="角色名称"></el-table-column>
            <el-table-column prop="roleCode" label="角色编码"></el-table-column>
            <el-table-column prop="roleNum" label="数量"></el-table-column>
            <el-table-column prop="roleIntro" label="备注" width="240" show-overflow-tooltip></el-table-column>
            <el-table-column prop="action" label="操作" width="280">
              <template slot-scope="scope">
                <span style="display: none;"></span>
                <el-button v-if="hasTableMember" type="primary" size="small" @click="handleSet(scope.row)">
                  成员
                </el-button>
                <el-button v-if="hasTableEdit" type="primary" size="small" @click="handleEdit(scope.row)">
                  编辑
                </el-button>
                <el-button v-if="hasTableDel" type="danger" size="small" @click="handleDelete(scope.row)">
                  删除
                </el-button>
              </template>
            </el-table-column>
            <div class="empty-content" slot="empty">
              <i class="iconfont iconwushuju"></i>
              <p>暂无数据</p>
            </div>
          </el-table>
          <el-pagination
            v-if="total > 10"
            :page-size="pageSize"
            :current-page="pageNo"
            layout="total, sizes, prev, pager, next, jumper"
            :total="total"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
        <div class="tree-container">
          <div class="title">
            <span>菜单分配</span>
            <el-button v-if="hasSaveBtn" type="primary" size="small" @click="handleSaveMenu">保存</el-button>
          </div>
<!--          <div class="filter">-->
<!--            <el-input-->
<!--              @input="handleInput"-->
<!--              size="small"-->
<!--              v-model="filterText"-->
<!--              placeholder="请输入关键字">-->
<!--            </el-input>-->
<!--          </div>-->
          <div class="menus">
            <el-tree
              v-loading="treeLoading"
              class="menu-filter-tree"
              ref="tree"
              show-checkbox
              check-strictly
              highlight-current
              :default-checked-keys="selectKeys"
              :data="menus"
              :props="defaultProps"
              node-key="id"
              default-expand-all
              :filter-node-method="filterNode"
              @check="handleTreeChange">
            </el-tree>
          </div>
        </div>
      </div>
      <add-role
        :visible="visible"
        :type="type"
        :option="currentData"
        :loading="loading"
        @cancel="visible = false"
        @submit="handleSave">
      </add-role>
      <set-role-member
        :visible="memberVisible"
        :roleId="roleId"
        @cancel="handleCancel">
      </set-role-member>
    </div>
  </div>
</template>

<script>
import addRole from '@/components/corp/addRole';
import setRoleMember from '@/components/corp/setRoleMember';

export default {
  components: {
    addRole,
    setRoleMember
  },
  data() {
    return {
      classType: '1',
      roleType: '1', // 1：系统角色；2：项目角色
      pageNo: 1,
      pageSize: 10,
      total: 0,
      tableData: [],
      tableLoading: false,
      importLoading: false,
      tmpLoading: false,
      currentKey: '',
      // 权限树
      menus: [],
      treeLoading: false,
      selectKeys: [],
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      filterText: '',
      // 设置机构
      loading: false,
      visible: false,
      type: '',
      currentData: {},
      // 添加成员
      roleId: '',
      memberVisible: false
    };
  },
  computed: {
    userId() {
      return this.$store.state.userInfo.uuid;
    }
  },
  watch: {
    visible(val) {
      if (!val) {
        this.loading = false;
      }
    },
    classType(val) {
      this.getTableData();
    },
    async currentKey(val) {
      if (val) {
        this.selectKeys = [];
        this.$nextTick(() => {
          this.$refs.tree.setCheckedKeys(this.selectKeys, true);
        });
        this.treeLoading = true;
        const { success, data: {
          data
        }} = await this.$Model.getRolePermissionTree({
          id: this.currentKey
        });
        this.treeLoading = false;
        if (success && data) {
          this.selectKeys = this.getSelectKeys(data);
          this.$nextTick(() => {
            this.$refs.tree.setCheckedKeys(this.selectKeys, true);
          });
        }
      }
    }
  },
  created() {
    this.getMenuTree();
    this.getTableData();
  },
  methods: {
    /**
     * 获取角色
     */
    async getTableData() {
      const params = {
        classType: this.classType,
        roleType: this.roleType,
        pageNum: this.pageNo,
        pageSize: this.pageSize,
      };
      this.tableLoading = true;
      const { success, data: {
        data
      }} = await this.$Model.getRoleList(params);
      this.tableLoading = false;
      if (success) {
        this.tableData = data.list || [];
        this.total = data.total || 0;
        this.currentKey = this.tableData[0]
          ? this.tableData[0].id
          : '';
      }
    },
    // 获取用户菜单权限
    async getMenuTree() {
      const params = {
        userId: this.userId
      };
      this.treeLoading = true;
      const { success, data: {
        data
      }} = await this.$Model.getUserPermissionTree(params);
      this.treeLoading = false;
      if (success && data) {
        this.menus = this.setMenuList(data || []);
      }
    },
    setMenuList(list, idList = []) {
      return list && list.map(item => {
        const { id, parentId, children } = item;
        const ids = [id];
        parentId && parentId !== '0' && ids.push(parentId);
        const newList = [...new Set([...idList, ...ids])];
        if (children && children.length) {
          return {
            ...item,
            idList: newList,
            children: this.setMenuList(children, newList)
          };
        }
        return {
          ...item,
          idList: newList
        };
      }) || [];
    },
    /**
     * 获取当前角色的权限ID
     * @param {Array} data
     * @param {Array} keys
     */
    getSelectKeys(data = [], keys = []) {
      const result = keys;
      data && data.forEach(item => {
        const { children, isCheck, id } = item;
        if (isCheck === '1') result.push(id);
        if (children && children.length) {
          this.getSelectKeys(children, result);
        }
      });
      return result;
    },
    clear() {
      this.pageNo = 1;
      this.pageSize = 10;
      this.tableLoading = false;
      this.total = 0;
    },
    // 切换类型
    tabChange(type) {
      this.classType = type;
    },
    handleSearch() {
      this.clear();
      this.getTableData();
    },
    handleRefresh() {
      this.clear();
      this.getTableData();
    },
    /**
     * pageSize 改变时会触发
     * @param pageSize 每页条数
     */
    handleSizeChange(pageSize) {
      this.pageNo = 1;
      this.pageSize = pageSize;
      this.getTableData();
    },
    /**
     * currentPage 改变时会触发
     * @param pageNo 当前页
     */
    handleCurrentChange(pageNo) {
      this.pageNo = pageNo;
      this.getTableData();
    },
    // 设置成员
    handleSet(row) {
      this.roleId = row.id;
      this.memberVisible = true;
    },
    // 取消
    handleCancel() {
      this.memberVisible = false;
      this.roleId = '';
    },
    setChildrenCheck(hasCheck, list) {
      list.forEach(item => {
        const { id, children } = item;
        const index = this.selectKeys.indexOf(id);
        if (hasCheck) {
          if (index < 0) {
            this.selectKeys.push(id);
          }
        } else {
          this.selectKeys.splice(index, 1);
        }
        if (children && children.length) {
          this.setChildrenCheck(hasCheck, children);
        }
      });
    },
    // 过滤节点
    filterNode(value, data) {
      if (!value) return true;
      return data.name.indexOf(value) !== -1;
    },
    handleInput(val) {
      this.$refs.tree && this.$refs.tree.filter(val);
      setTimeout(() => {
      }, 300);
    },
    // 树节点修改
    handleTreeChange(data, options) {
      const { children, idList, id } = data;
      const index = this.selectKeys.indexOf(id);
      const hasIncldues = index > -1;
      if (hasIncldues) {
        this.selectKeys.splice(index, 1);
      } else {
        this.selectKeys = [...new Set([...this.selectKeys, ...idList])];
      }
      this.setChildrenCheck(!hasIncldues, children);
      this.$refs.tree.setCheckedKeys(this.selectKeys, true);
    },
    // 保存菜单设置
    async handleSaveMenu() {
      if (!this.currentKey) {
        this.$message.warning('请选择角色');
        return;
      }
      const { success } = await this.$Model.setRolePermissions({
        roleId: this.currentKey,
        sysRolePermissions: this.selectKeys.map(menuId => ({
          roleId: this.currentKey,
          menuId
        }))
      });
      success && this.$message.success('保存成功');
    },
    // 当某一行被双击时会触发该事件
    handleRowClick(row, column, event) {
      this.currentKey = row.id;
    },
    // 新增
    handleAdd() {
      this.type = 'add';
      this.currentData = {};
      this.visible = true;
    },
    // 编辑
    handleEdit(row) {
      this.type = 'edit';
      this.currentData = { ...row };
      this.visible = true;
    },
    // 删除
    handleDelete(row) {
      this.$confirm('此操作将删除该角色, 是否继续?', '提示', {
        type: 'warning'
      }).then(async () => {
        const { success } = await this.$Model.delSystemRole({
          ids: row.id
        });
        if (success) {
          this.getTableData();
          this.$message.success('删除成功');
        }
      });
    },
    // 保存
    async handleSave(data) {
      const params = {
        ...this.currentData,
        roleType: this.roleType,
        ...data,
      };
      if (this.classType) {
        params.classType = this.classType;
      }
      this.loading = true;
      if (this.type === 'add') delete params.id;
      const { success } = this.type === 'add'
        ? await this.$Model.addSystemRole(params)
        : await this.$Model.updateSystemRole(params);
      this.loading = false;
      if (success) {
        this.$message.success('保存成功');
        this.getTableData();
        this.visible = false;
      }
    }
  }
};
</script>

<style scoped lang="scss">
  @import "../../assets/styles/table";
  @import "../../assets/styles/dialog";

  .role-page {
    width: 100%;
    height: 100%;
    padding: 20px 30px;
    background-color: $baseBg;
    .main {
      width: 100%;
      height: 100%;
      padding: 20px;
      background-color: $mainBg;
      .header {
        width: 100%;
        height: 100px;
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        margin-bottom: 20px;
        .title {
          font-size: 20px;
        }
        .search-container {
          display: flex;
          justify-content: space-between;
          align-items: center;
          .search-input {
            display: flex;
            height: 100%;
            .tabs {
              display: flex;
              margin-right: 20px;
              box-shadow: 0 0 3px 0 $mainBg;
              li {
                width: 120px;
                height: 40px;
                background: #fff;
                color: rgba(0, 0, 0, .8);
                display: flex;
                justify-content: center;
                align-items: center;
                cursor: pointer;
                transition: all .2s;
                &.active, &:hover {
                  background: $linearG;
                  color: #fff;
                }
                &:nth-child(1) {
                  border-radius: 5px 0 0 5px;
                }
                &:nth-last-child(1) {
                  border-radius: 0 5px 5px 0;
                }
              }
            }
            .el-input {
              width: 260px;
              margin-right: 20px;
            }
          }
        }
        .btns {
          .upload-file {
            position: relative;
            cursor: pointer;
            .file {
              position: absolute;
              width: 100%;
              height: 100%;
              top: 0;
              left: 0;
              right: 0;
              bottom: 0;
              opacity: 0;
              cursor: pointer;
            }
          }
        }
      }
      .content {
        width: 100%;
        height: calc(100% - 100px);
        display: flex;
        justify-content: space-between;
        .table-container {
          width: calc(100% - 420px);
          height: 100%;
          /deep/ .el-table {
            height: calc(100% - 50px);
            .el-table__body-wrapper {
              height: calc(100% - 40px);
              overflow-y: auto;
              tr.current-row {
                > td {
                  background-color: $mainBorder;
                }
              }
              .btn {
                color: $mainColor;
                cursor: pointer;
                &:hover {
                  text-decoration: underline;
                }
              }
            }
          }
        }
        .tree-container {
          width: 400px;
          height: calc(100% - 20px);
          padding-left: 20px;
          border-left: 1px dotted #fff;
          .title {
            width: 100%;
            height: 50px;
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 0 20px;
          }
          .filter {
            width: 100%;
            margin-top: 10px;
          }
          .menus {
            width: 100%;
            height: calc(100% - 60px);
            overflow-y: auto;
            .el-tree {
              background: $mainBg;
              color: #fff;
              /deep/ .el-tree-node__content {
                &:hover {
                  color: $mainColor;
                  background: transparent;
                }
              }
            }
            .el-tree {
              /deep/ .el-tree-node.is-checked > .el-tree-node__content {
                color: $mainColor;
                background: $baseBg;
              }
              /deep/ .el-tree-node.is-focusable:not(.is-checked) > .el-tree-node__content {
                background: transparent;
              }
            }
          }
        }
      }
    }
  }
</style>
